import socket
import logging

from CalcMSE import transform_obj, calculate_mse
from CalcMSE import MSEData

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler("logs/wits_a_receiver.log"),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)


class WITSAReceiver:
    def __init__(self, host, port):
        self.host = host
        self.port = port
        self.socket = None
        self.connected = False
        self.buffer = ""

        # 字段编码到MSEData属性的映射
        self.field_mapping = {
            "0105": "date",  # 日期
            "0106": "time",  # 时间
            "0108": "depth",  # 井深
            "0118": "TQ_surf",  # 顶驱扭矩
            "0120": "RPM_surf",  # 顶驱转速
            "0121": "vertical_pipe_press",  # 立管压力
            "0130": "Q",  # 入口流量
            "0113": "ROP",  # 钻时
            "0116": "WOB"  # 钻压
        }

        # 中文字段名映射，用于打印
        self.chinese_names = {
            "date": "日期",
            "time": "时间",
            "depth": "井深",
            "TQ_surf": "顶驱扭矩",
            "RPM_surf": "顶驱转速",
            "vertical_pipe_press": "立管压力",
            "Q": "入口流量",
            "ROP": "钻时",
            "WOB": "钻压"
        }

    def start_server(self):
        """启动WITS-A服务器"""
        try:
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.socket.bind((self.host, self.port))
            self.socket.listen(1)
            self.connected = True
            logger.info(f"WITS-A服务器已启动，监听 {self.host}:{self.port}")
            return True
        except Exception as e:
            logger.error(f"启动服务器失败: {e}")
            return False

    def parse_wits_record(self, record_data):
        """解析WITS-A记录并返回MSEData对象"""
        # 创建新的MSEData对象
        mse_data = MSEData()

        # 分割记录为多行
        lines = record_data.strip().split('\r\n')

        # 检查记录类型（第一条有效数据行）
        record_type = None
        for line in lines:
            if line and not line.startswith('&&') and not line.startswith('!!'):
                # 提取记录类型（前两位）
                record_type = line[:2]
                break

        # 只处理01类型记录
        if record_type != "01":
            logger.debug(f"跳过非01类型记录: {record_type}")
            return None

        # 解析字段并填充MSEData对象
        for line in lines:
            if line and not line.startswith('&&') and not line.startswith('!!'):
                # 提取字段编码（前4位）
                field_code = line[:4]

                # 检查是否是需要提取的字段
                if field_code in self.field_mapping:
                    # 提取字段值（第4位之后的内容）
                    field_value = line[4:]
                    field_name = self.field_mapping[field_code]

                    # 根据字段类型设置值
                    try:
                        if field_name in ["date", "time"]:
                            # 日期和时间保持为字符串
                            setattr(mse_data, field_name, field_value)
                        else:
                            # 其他字段转换为浮点数
                            setattr(mse_data, field_name, float(field_value))
                    except (ValueError, TypeError) as e:
                        logger.warning(f"字段 {field_name} 值转换失败: {field_value}, 错误: {e}")
                        # 转换失败时设置为None
                        setattr(mse_data, field_name, None)

        return mse_data

    def handle_client(self, client_socket):
        """处理客户端连接"""
        logger.info("客户端已连接")

        try:
            while self.connected:
                # 接收数据
                data = client_socket.recv(4096).decode('ascii', errors='ignore')
                if not data:
                    break

                # 添加到缓冲区
                self.buffer += data

                # 处理缓冲区中的完整记录
                while '!!' in self.buffer:
                    # 查找记录开始和结束位置
                    start_pos = self.buffer.find('&&')
                    end_pos = self.buffer.find('!!')

                    if start_pos == -1 or end_pos == -1 or end_pos < start_pos:
                        # 如果没有完整的记录，等待更多数据
                        break

                    # 提取完整记录
                    record_data = self.buffer[start_pos:end_pos + 2]
                    self.buffer = self.buffer[end_pos + 2:]

                    # 解析记录
                    mse_data = self.parse_wits_record(record_data)

                    # 打印解析结果
                    if mse_data:
                        logger.info("=== 解析到01类型记录 ===")
                        for field in mse_data.__dataclass_fields__:
                            value = getattr(mse_data, field)
                            if value is not None:
                                chinese_name = self.chinese_names.get(field, field)
                                logger.info(f"{chinese_name}: {value}")
                        mse_trans_data  = transform_obj(mse_data)
                        mse_total, mse_downhole,DOC,DS = calculate_mse(mse_trans_data,8.5,466,0.25,9.5)
                        logger.info("----------计算结果---------------")
                        logger.info("mse_total: %.2f",mse_total)
                        logger.info("mse_downhole: %.2f",mse_downhole)
                        logger.info("DOC: %.2f",DOC)
                        logger.info("DS: %.2f",DS)
                        logger.info("=" * 30)

                    else:
                        logger.debug("跳过非01类型记录或无效记录")

        except Exception as e:
            logger.error(f"处理客户端数据时出错: {e}")
        finally:
            client_socket.close()
            logger.info("客户端连接已关闭")

    def run(self):
        """运行服务器"""
        if not self.start_server():
            return

        try:
            while self.connected:
                logger.info("等待客户端连接...")
                client_socket, client_address = self.socket.accept()
                logger.info(f"接收到来自 {client_address} 的连接")

                # 处理客户端
                self.handle_client(client_socket)

        except KeyboardInterrupt:
            logger.info("用户中断服务器")
        except Exception as e:
            logger.error(f"服务器运行出错: {e}")
        finally:
            self.stop_server()

    def stop_server(self):
        """停止服务器"""
        if self.socket:
            self.socket.close()
        self.connected = False
        logger.info("WITS-A服务器已停止")


def main():
    # 配置服务器信息
    HOST = "0.0.0.0"  # 监听所有接口
    PORT = 5001  # WITS-A服务器端口

    # 创建接收器实例
    receiver = WITSAReceiver(HOST, PORT)

    # 运行服务器
    receiver.run()


if __name__ == "__main__":
    main()